package com.xingda.packing.dmss.http;

import com.alibaba.fastjson.JSONObject;
import com.xingda.packing.dmss.cache.TokenCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StopWatch;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
public class BaseHttp {

    /**
     * 毫秒数
     */
    private final static long sleepTime = 1500;

    private final static int timeOut = 10000;

    private final static String X_TOKEN = "X-Token";


    /**
     * 获取HttpResponse
     */
    public static JSONObject get(String url, List<NameValuePair> nameValuePairList) {
        JSONObject entityJson = null;
        HttpGet httpGet = null;
        try {
            String paramStr = EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairList, "UTF-8"));
            httpGet = new HttpGet(url + "?" + paramStr);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();
            httpGet.setConfig(requestConfig);
            entityJson = execute(httpGet, url);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
        }
        return entityJson;
    }

    /**
     * 发送JSON格式的数据请求
     *
     * @param url  接口地址
     * @param json 参数JSON格式
     */
    public static JSONObject postBody(String url, JSONObject json) {
        return postBody(url, json.toJSONString());
    }

    /**
     * 发送JSON格式字符串的数据请求
     *
     * @param url        接口地址
     * @param jsonString 参数JSON格式字符串
     */
    public static JSONObject postBody(String url, String jsonString) {
        JSONObject entityJson = null;
        HttpPost httpPost = null;
        try {
            httpPost = new HttpPost(url);
            // 构建消息实体
            StringEntity entity = new StringEntity(jsonString, StandardCharsets.UTF_8);
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();
            httpPost.setConfig(requestConfig);
            entityJson = execute(httpPost, url);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpPost != null) {
                httpPost.releaseConnection();
            }
        }
        return entityJson;
    }

    private static JSONObject execute(HttpUriRequest request, String url) throws Exception {
        Header header = request.getFirstHeader(X_TOKEN);
        if (header == null && !url.contains("getToken")) {
            request.addHeader(X_TOKEN, TokenCache.getToken());
        }
        JSONObject entityJson = null;
        StopWatch stopWatch = new StopWatch("信息中心读取数据");
        int i = 0;
        int httpStatus = -1;

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(10000)
                .setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000).build();
        while (i <= 3 && httpStatus != HttpStatus.SC_OK) {
            log.info("url：{};第{}次读取", url, i + 1);
            stopWatch.start("url：" + url + ";第" + (i + 1) + "次读取");
            HttpClient httpclient = HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .build(); // 定义一个http客户端请求

            try {
                HttpResponse result = httpclient.execute(request); // 执行http请求
                stopWatch.stop();
                if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity httpEntity = result.getEntity();
                    String entityStr = EntityUtils.toString(httpEntity, "UTF-8");
                    entityJson = JSONObject.parseObject(entityStr);
                } else {
                    TimeUnit.MILLISECONDS.sleep(sleepTime);
                }
                httpStatus = result.getStatusLine().getStatusCode();
            } catch (Exception e) {
                log.info(e.getMessage());
                stopWatch.stop();
                TimeUnit.MILLISECONDS.sleep(sleepTime);
                e.printStackTrace();
            }
            log.info("{}请求url-{}，状态为：{},{}", request.getMethod(), url, httpStatus, stopWatch.getTotalTimeMillis());
            i++;
        }
        return entityJson;
    }

}
